#include <cstdlib>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

// auto inc init val
int work_id_inc = 1;
// timelen 5 ~ 20 
// int timelen = rand() % 16 + 5;

// simple_turn_timer timer
int simple_turn_timer = 0;
int simple_turn_count = 0;

// define program 
struct Work{
  int id, w, ht, ts; //进程id, 优先级, 到达时间 timeslicen
  int st, ed; // start time, end time
  int cpuw, iow, cput, iot; // cpu wait io wait cput cost io cost
  int cpust, cpued, iost, ioed;
  bool in_wait, is_ok, working; // progress status
  bool is_first_cpu; // 标记是否是第一次cpu执行， 统计cpu开始执行时间
  bool is_first_io; // 标记是否是第一次cpu执行， 统计cpu开始执行时间
  vector<pair<int, int>> *jobs; // 片段序列 first is type { cpu | io { 1 | 2, second is time { 200
  int sgp;// segment point 
  friend ostream & operator << (ostream &out,const Work &w) {
	  out << w.id << " " << w.w << " " << w.ht << " " << (*w.jobs).size() << " ";
	  for (auto x : *w.jobs){
		  out << x.second << " ";
	  }
	  out << endl;
    return out;
  }
  bool operator < (const Work &w)const {
    return ht < w.ht;
  }
  bool operator == (Work* w)const {
    return id < w->id;
  }
};

// cpu, io queue
vector<Work*> qwait;
// queue<Work> qok;

// cpu, io
bool cpu, io;
void datacreate(int n){
  if ( n > 20) {
    cout << "进程数量不能大于20" << endl;
    exit(1);
  }
  fstream f ("job", ios::out);
  vector<Work> jobs;
  f << n << endl;
  for (int i = 0; i < n; i++){
    Work w = {.id=work_id_inc++,.w = rand() % 32, .ht= rand() % 1000,};
    int j = rand() % 7 + 3;
    for (int k = 0; k < j; k++){
    	int type = k % 2 + 1;
    	int nt = -1; // cost time
    	if (type == 1){
    		nt = rand() % 41 + 10;
    	} else if (type == 2){
    		nt = rand() % 201 + 100;
    	} else {
    		cout << "data create error, nt is -1" << endl;
    		exit(1);
    	}
    	(*w.jobs).push_back({type,nt});
    }
    jobs.push_back(w);
  }
  sort(jobs.begin(), jobs.end());
  for (auto x: jobs){
    f << x;
  }
  f.close();
}

void init(int n){
  datacreate(n);
}

// simple_turn
void simple_turn(int timelen, char* save_file){
  fstream f("job", ios::in);
  fstream f2(save_file, ios::out);
  Work *cpuworkingWork = nullptr;
  Work *ioworkingWork = nullptr;
  int n;
  f >> n;
  int tn = n;
  vector<Work*> jobs;
  vector<Work*> res;
  int workJobsize  = 0;
  while (tn--) {
    Work *w = new Work{}; 
    f >> w->id>> w->w >> w->ht;
	f >> workJobsize;
	w->jobs = new vector<pair<int,int>>();
	int type, ct;
	for (int i = 0; i < workJobsize; i++){
		int type = i % 2 + 1, ct;
		f >> ct;
		(*w->jobs).push_back({type, ct});
	}
	w->sgp = 0;
	w->in_wait = false;
	w->is_ok = false;
	w->working = false;
	jobs.push_back(w);
  }
  // input finished
  cout << jobs[0]->id << endl;
  bool compelte = false;
  int tltltl = 0;
  for (int i = 0; i < 3800; i++){
	  bool compelte = false;
	  if (cpu && cpuworkingWork != nullptr){
		  int _sgp = cpuworkingWork->sgp;
		  cout << " 当前时间是 " << simple_turn_count << " ,";
		  cout << " " << cpuworkingWork->id << " 进程 " << cpuworkingWork->sgp << " 序列正在使用cpu," << "剩余 " << (*cpuworkingWork->jobs)[_sgp].second << endl;
		  cpuworkingWork->cput++;
		  (*cpuworkingWork->jobs)[_sgp].second--;
		  if ((*cpuworkingWork->jobs)[_sgp].second == 0){
			  compelte = true;
			  cout << cpuworkingWork->id <<" 号进程" << "第" << cpuworkingWork->sgp << "序列"  <<"完成" << endl;
			  cpuworkingWork->ts ++;
			  cpuworkingWork->sgp ++;
			  cpuworkingWork->cpued = simple_turn_count;
			  if (cpuworkingWork->sgp == (*cpuworkingWork->jobs).size()){
				  cout << cpuworkingWork->id << " 号进程 " << "进程所有序列执行完毕" << endl;
				  cpuworkingWork->working = false;
				  cpuworkingWork->is_ok = true;
				  qwait.erase(find(qwait.begin(),qwait.end(),cpuworkingWork));
				  res.push_back(cpuworkingWork);
				  cpuworkingWork = nullptr;
				  // res.push_back(WorkResult{.id = w.id,.w=w.w,.ht=w.ht,.ed=simple_turn_count+1,.tl=w.ts,.rw=w.cpued -w.cpust -w.cput, .cpt=w.cput,.iow = w.ioed - w.iost - w.iot, .iot=w.iot});
			  } else {
				  qwait.erase(find(qwait.begin(),qwait.end(),cpuworkingWork));
				  qwait.push_back(cpuworkingWork);
				  cpuworkingWork->working = false;
				  cpuworkingWork = nullptr;
			  }
			  cpu = false;
		  }
	  }

	  if (io && ioworkingWork != nullptr){
		  int _sgp = ioworkingWork->sgp;
		  cout << " 当前时间是 " << simple_turn_count << " ,";
		  cout << " " << ioworkingWork->id << " 进程 " << ioworkingWork->sgp << " 序列正在使用io," << "剩余" << (*ioworkingWork->jobs)[_sgp].second << endl;
		  (*ioworkingWork->jobs)[_sgp].second--;
		  ioworkingWork->iot ++;
		  if ((*ioworkingWork->jobs)[_sgp].second == 0){
			  compelte = true;
			  cout << ioworkingWork->id <<" 号进程" << "第" << ioworkingWork->sgp << "序列"  <<"完成" << endl;
			  ioworkingWork->ts ++;
			  ioworkingWork->sgp ++;
			  ioworkingWork->ioed = simple_turn_count;
			  if (ioworkingWork->sgp == (*ioworkingWork->jobs).size()){
				  cout << ioworkingWork ->id << " 号进程 " << "进程所有序列执行完毕" << endl;

				  ioworkingWork->working = false;
				  ioworkingWork->is_ok = true;
				  // qwait.erase(find(qwait.begin(),qwait.end(), ioworkingWork));
				  res.push_back(ioworkingWork);
				  ioworkingWork = nullptr;
				  //res.push_back(WorkResult{.id = w.id,.w=w.w,.ht=w.ht,.ed=simple_turn_count+1,.tl=w.ts,.rw=w.cpued -w.cpust -w.cput, .cpt=w.cput,.iow = w.ioed - w.iost - w.iot, .iot=w.iot});
			  } else {
				  // qwait.erase(find(qwait.begin(),qwait.end(),ioworkingWork));
				  // qwait.push_back(ioworkingWork);
				  ioworkingWork->working = false;
				  ioworkingWork = nullptr;
			  }
			  io = false;
		  }
	  }
	  simple_turn_timer ++;
	  simple_turn_count ++;
	  if (compelte || simple_turn_timer % timelen == 0){

		  cout << "当前时间片共计花费" << ++tltltl << "片" << endl;
		  simple_turn_timer = 0;
		  for (auto w: jobs){ 
			  if (w->in_wait) continue; 
			  if (w->ht < simple_turn_count){ 
				  cout << "当前时间是" << simple_turn_count << " ";
				  cout << "等待队列qwait当前状态";
				  for (auto x: qwait){cout << x->id << "当前working" << x->working << " ";};
				  w->in_wait = true;
				  w->st = simple_turn_count;
				  cout << "进程" << w->id << " 被加入到等待队列中" << endl;
				  qwait.push_back(w);
			  }
		  };
		  if (cpu && cpuworkingWork!=nullptr){
			  cpuworkingWork->ts ++;
			  cpuworkingWork->working = false;
			  cout <<"cpu 锁释放 ";
			  cpu = false;
			  qwait.erase(find(qwait.begin(),qwait.end(),cpuworkingWork));
			  qwait.push_back(cpuworkingWork);
			  cout << "进程" << cpuworkingWork->id <<"结束cpu占用 "; 
			  cout << "当前时间是" << simple_turn_count << " ";
			  cout << "等待队列qwait当前状态";
			  for (auto x: qwait){cout << x->id << "当前working" << x->working << " ";};
		  }
		  if (!cpu){
			  for (auto x: qwait){
				  if (x->working) continue;
				  if (cpu) continue;
				  if ((*x->jobs)[x->sgp].first == 1){
					  x->working = true;
					  cpu = true;
					  cpuworkingWork = x;
					  cout << "进程" << x->id << " 开始占用cpu " << endl;
					  // 记录cpu开始工作时间。
					  if (!cpuworkingWork->is_first_cpu){
						  cpuworkingWork->is_first_cpu = true;
						  cpuworkingWork->cpust = simple_turn_count;
					  }
				  }
			  }
		  }
		  if (io && ioworkingWork!=nullptr){
			  ioworkingWork->ts ++;
			  ioworkingWork->working = false;
			  io = false;
			  qwait.erase(find(qwait.begin(),qwait.end(),ioworkingWork));
			  qwait.push_back(ioworkingWork);
			  cout <<"io 锁释放 ";
			  cout << "进程" << ioworkingWork->id <<"结束io占用 "; 
			  cout << "当前时间是" << simple_turn_count << " ";
			  cout << "等待队列qwait当前状态 是";
			  for (auto x: qwait){cout << x->id << "当前working" << x->working << " ";};
		  }
		  if (!io){
			  for (auto x: qwait){
				  if (x->working) continue;
				  if (io) continue;
				  if ((*x->jobs)[x->sgp].first == 2){
					  x->working = true;
					  io = true;
					  ioworkingWork = x;
					  cout << "进程" << x->id << " 开始占用io " << endl;
					  if (!ioworkingWork->is_first_io){
						  ioworkingWork->is_first_io= true;
						  ioworkingWork->iost = simple_turn_count;
					  }
				  }
			  }
		  }

	  }
  }
  jobs.clear();
  // 输出结果
  f2 << n << " " << timelen << endl; 
  int cpu_w = 0, cpu_t = 0, io_w = 0, io_t = 0;
  double turn_s = 0, turn2_s = 0;
  for (auto x: res){
	  x->cpuw = x->cpued - x->cpust - x->cput;
	  x->iow = x->ioed - x->iost - x->iot;
    x->ed = min(x->cpued, x->ioed);
    cpu_w += x->cpuw; cpu_t += x->cput;
    io_w += x->iow; io_t += x->iot;
	  double turn = max(x->ioed, x->cpued) - x->ht;
	  double runt = x-> iot + x->cput; 
    turn_s += turn; turn2_s += turn / runt; 
    f2 << x->id << " " << x->w << " " << x->ht << " " << x->ed << " " << x->ts << " " << x->cpuw <<  " " << x->cput << " "
      << x->iow << " " << x->iot << " " << turn << " "
      << turn / runt << endl;
  }
  f2 << cpu_w / n << " " << cpu_t / n << " " << io_w / n << " " << io_t /n << " " << turn_s / n << " " << turn2_s / n << endl;

  /*
  for (auto x : res ) {
    f2 << "进程id " << x->id 
		  << " cpu开始执行时刻\t" << x->cpust << "\tcpu结束执行时刻\t" << x->cpued << endl;
	  f2 << "cpu 执行时间\t" << x->cput << "\t cpu 等待时间" << x->cpuw << endl;
	  f2 << "io开始执行时刻\t" << x->iost << "\tio结束执行时刻\t" << x->ioed << endl;
	  x->iow = x->ioed - x->iost - x->iot;
	  f2 << "io 执行时间\t" << x->iot << "\t io 等待时间" << x->iow << endl;
	  f2 << "开始执行时刻\t" << min(x->iost, x->cpust) << "\t 结束执行时间" << max(x->ioed, x->cpued)<< endl;
	  int turn = max(x->ioed, x->cpued) - x->ht;
	  int runt = x-> iot + x->cput;
	  f2 << "周转时间\t" << turn << "\t 带权周转时间" << turn / runt << endl;
  }
  */
  // 带权周转时间，很奇怪
  f.close();
  f2.close();
}



int main (int argc, char *argv[])
{
   // init(5);
  if (argc < 3){
    exit(1);
  }
  int timelen = stoi(argv[1]);
  simple_turn(timelen, argv[2]);
  return 0;
}
